class TicketMail
  require 'net/imap'
  require 'tmail'
  require 'json'
  TICKET_MAIL_CONFIG_PATH = File.expand_path("#{File.dirname(__FILE__)}/../../config/ticket_mailer.yml")

  attr_accessor :project
  
  def initialize(project)
    @conf = {}
    yml_conf = YAML.load_file(TICKET_MAIL_CONFIG_PATH)  
    unless yml_conf[project]
      raise "Cannot find email configuration for: #{project} in config file: #{TICKET_MAIL_CONFIG_PATH}"
    end
    #grab project
    self.project = Project.find_by_identifier(project, 
                                              :include=>:enabled_modules, 
                                              :conditions=>"enabled_modules.name='ticket_mails'")
                                                
    unless self.project.nil? #project found
      @conf = yml_conf[project].symbolize_keys
      @conf[:issue].symbolize_keys!
      #make imap object
      @imap = Net::IMAP.new(@conf[:email_server],@conf[:email_port], @conf[:use_ssl])
      connect
     end
     
  end
  
  def get_status    
    @imap.status(@conf[:email_folder], ["MESSAGES", "RECENT", "UNSEEN"])
  end
  #fet all mails from imap create issues from them and delete them from imap
  def process_all
    issues = []
    @imap.search(['ALL']).each do |msg_id|
      @msg = {}
      @email = TMail::Mail.parse(@imap.fetch(msg_id,['RFC822'])[0].attr['RFC822'])      
      @msg[:subject] = @email.subject
      @msg[:body]= @email.body
      @msg[:from]= @email.from[0]
      issues << create_issue        
      #Mark message as deleted and it will be removed from storage when user session closd
      @imap.store(msg_id, "+FLAGS", [:Deleted])
    end
    # tell server to permanently remove all messages flagged as :Deleted
    @imap.expunge()
    #return list of created issues
    issues
  end
  private
  
    def connect  
      @imap.login(@conf[:email_login], @conf[:email_password])
      @imap.select(@conf[:email_folder]) 
    end
     
    #TODO
    # - check for error creating an issue
    #- also check for user from yaml
    def create_issue         
      # If the email exists for a user in the current project,
      # use that user as the author. 
      author = User.find_by_mail @msg[:from], :select=>"users.id", :joins=>"inner join members on members.user_id = 'users.id'",
                                :conditions=>["members.project_id=?", self.project.id]

      if author.nil? #author not found
        #try to set from author_id in config file or use the first user that is returned from the Member model
        author_id = @conf[:issue][:author_id] || (Member.find_by_project_id self.project.id).id
      else
          author_id = author.id
      end
      
      #not so nice to have it here .. needs optimizing
      if data = parse_mail(@msg[:body])
        #find tracker by name, no check if he belongs to current project
        if tracker = Tracker.find(:first, :conditions => ['name= ?', data[:tracker]])
          tracker_id = tracker.id
        end
        #find status by name  no check if  belongs to current project
        if priority = Enumeration.find(:first, :conditions => ["name= ? AND opt = 'IPRI'", data[:priority]])
          priority_id = priority.id
        end
        msg_body = data[:full_text]
      end
      
      issue = Issue.create(
          :subject      => @msg[:subject],
          :description  => msg_body || @msg[:body],
          :priority_id  => priority_id || @conf[:issue][:priority_id],
          :project_id   => self.project.id,
          :tracker_id   => tracker_id || @conf[:issue][:tracker_id],
          :author_id    => author_id,
          :status_id    => @conf[:issue][:status_id]        
      )

    end
    
    # parse the emailbody for hidden json string
    # ==Example
    #  [params_start]{"text":"asdasdasd","priority":"Normal","tracker":"Bug"}[params_end]
    def parse_mail(body)
      data = nil
      if body =~ /\[params_start](.*)\[params_end]/m
        data = JSON.parse($1).symbolize_keys
        #grab fulltext by substracting 
        data[:full_text] = body.gsub(/\[params_start].*\[params_end]/m, '')
      end
      data
    end
 end   
 
#some old imap stuff
#env = @imap.fetch(msg_id, "ENVELOPE")[0].attr["ENVELOPE"]
#@msg[:from]== "#{env.from[0].mailbox}@#{env.from[0].host}"
#@msg[:subject]= env.subject
#@msg[:body]= @imap.fetch(msg_id,['RFC822.TEXT'])[0].attr['RFC822.TEXT']#just text
#@msg[:body]= @imap.fetch(msg_id,['RFC822'])[0].attr['RFC822']#whole body
#use tmail to do the parsing